﻿using RimWorld;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using Verse;
using Verse.Noise;

public class Verb_Self : Verb_Shoot
{
    protected override bool TryCastShot()
    {
        if (currentTarget.HasThing && currentTarget.Thing.Map != caster.Map)
        {
            return false;
        }
        ThingDef projectile = Projectile;
        if (projectile == null)
        {
            return false;
        }
        ShootLine resultingLine;
        bool flag = TryFindShootLineFromTo(caster.Position, currentTarget, out resultingLine);
        if (verbProps.stopBurstWithoutLos && !flag)
        {
            return false;
        }
        if (base.EquipmentSource != null)
        {
            base.EquipmentSource.GetComp<CompChangeableProjectile>()?.Notify_ProjectileLaunched();
            

            base.EquipmentSource.GetComp<CompApparelReloadable>()?.UsedOnce();
        }
        lastShotTick = Find.TickManager.TicksGame;
        Thing manningPawn = caster;
        Thing equipmentSource = base.EquipmentSource;
        CompMannable compMannable = caster.TryGetComp<CompMannable>();//Mannable，
        if (compMannable != null && compMannable.ManningPawn != null)
        {
            manningPawn = compMannable.ManningPawn;
            equipmentSource = caster;
        }
        Vector3 drawPos = caster.DrawPos;
        Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, resultingLine.Source, caster.Map);
        if (verbProps.ForcedMissRadius > 0.5f)
        {
            float num = verbProps.ForcedMissRadius;
            if (manningPawn != null && manningPawn is Pawn pawn)
            {
                num *= verbProps.GetForceMissFactorFor(equipmentSource, pawn);
            }
            float num2 = VerbUtility.CalculateAdjustedForcedMiss(num, currentTarget.Cell - caster.Position);
            if (num2 > 0.5f)
            {
                IntVec3 forcedMissTarget = GetForcedMissTarget(num2);
                if (forcedMissTarget != currentTarget.Cell)
                {
                    ThrowDebugText("ToRadius");
                    ThrowDebugText("Rad\nDest", forcedMissTarget);
                    ProjectileHitFlags projectileHitFlags = ProjectileHitFlags.NonTargetWorld;
                    if (Rand.Chance(0.5f))
                    {
                        projectileHitFlags = ProjectileHitFlags.All;
                    }
                    if (!canHitNonTargetPawnsNow)
                    {
                        projectileHitFlags &= ~ProjectileHitFlags.NonTargetPawns;
                    }
                    Explode(projectile2);
                    //projectile2.Launch(manningPawn, drawPos, forcedMissTarget, manningPawn, projectileHitFlags, preventFriendlyFire, equipmentSource);
                    return true;
                }
            }
        }
        ShotReport shotReport = ShotReport.HitReportFor(caster, this, currentTarget);
        Thing randomCoverToMissInto = shotReport.GetRandomCoverToMissInto();
        ThingDef targetCoverDef = randomCoverToMissInto?.def;
        if (verbProps.canGoWild && !Rand.Chance(shotReport.AimOnTargetChance_IgnoringPosture))
        {
            resultingLine.ChangeDestToMissWild_NewTemp(shotReport.AimOnTargetChance_StandardTarget, false,caster.Map);

            //resultingLine.ChangeDestToMissWild(shotReport.AimOnTargetChance_StandardTarget);
            ThrowDebugText("ToWild" + (canHitNonTargetPawnsNow ? "\nchntp" : ""));
            ThrowDebugText("Wild\nDest", resultingLine.Dest);
            ProjectileHitFlags projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld;
            if (Rand.Chance(0.5f) && canHitNonTargetPawnsNow)
            {
                projectileHitFlags2 |= ProjectileHitFlags.NonTargetPawns;
            }
            Explode(projectile2);
            //projectile2.Launch(manningPawn, manningPawn.DrawPos, resultingLine.Dest, manningPawn, projectileHitFlags2, preventFriendlyFire, equipmentSource, targetCoverDef);
            return true;
        }
        if (currentTarget.Thing != null && currentTarget.Thing.def.CanBenefitFromCover && !Rand.Chance(shotReport.PassCoverChance))
        {
            ThrowDebugText("ToCover" + (canHitNonTargetPawnsNow ? "\nchntp" : ""));
            ThrowDebugText("Cover\nDest", randomCoverToMissInto.Position);
            ProjectileHitFlags projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld;
            if (canHitNonTargetPawnsNow)
            {
                projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns;
            }
            Explode(projectile2);
            //projectile2.Launch(manningPawn, drawPos, manningPawn, manningPawn, projectileHitFlags3, preventFriendlyFire, equipmentSource, targetCoverDef);
            return true;
        }
        ProjectileHitFlags projectileHitFlags4 = ProjectileHitFlags.IntendedTarget;
        if (canHitNonTargetPawnsNow)
        {
            projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns;
        }
        if (!currentTarget.HasThing || currentTarget.Thing.def.Fillage == FillCategory.Full)
        {
            projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld;
        }
        ThrowDebugText("ToHit" + (canHitNonTargetPawnsNow ? "\nchntp" : ""));
        Explode(projectile2);
        //if (currentTarget.Thing != null)
        //{


        //    //projectile2.Launch(manningPawn, drawPos, manningPawn, manningPawn, projectileHitFlags4, preventFriendlyFire, equipmentSource, targetCoverDef);
        //    //ThrowDebugText("Hit\nDest", currentTarget.Cell);
        //}
        //else
        //{
        //    //projectile2.Launch(manningPawn, drawPos, manningPawn, manningPawn, projectileHitFlags4, preventFriendlyFire, equipmentSource, targetCoverDef);
        //    //ThrowDebugText("Hit\nDest", resultingLine.Dest);
        //}
        return true;
    }

    private void Explode(Projectile projectile2)
    {
        ThingDef def = projectile2.def;
        if (def.projectile.explosionEffect != null)
        {
            Effecter effecter = projectile2.def.projectile.explosionEffect.Spawn();
            effecter.Trigger(new TargetInfo(this.caster.Position, this.caster.Map), new TargetInfo(this.caster.Position, this.caster.Map));
            effecter.Cleanup();
        }
        GenExplosion.DoExplosion(this.caster.Position, this.caster.Map, def.projectile.explosionRadius, def.projectile.damageDef, this.caster, projectile2.DamageAmount, projectile2.ArmorPenetration, def.projectile.soundExplode,null, def,null, def.projectile.postExplosionSpawnThingDef, postExplosionSpawnThingDefWater: def.projectile.postExplosionSpawnThingDefWater, postExplosionSpawnChance: def.projectile.postExplosionSpawnChance, postExplosionSpawnThingCount: def.projectile.postExplosionSpawnThingCount, postExplosionGasType: def.projectile.postExplosionGasType, preExplosionSpawnThingDef: def.projectile.preExplosionSpawnThingDef, preExplosionSpawnChance: def.projectile.preExplosionSpawnChance, preExplosionSpawnThingCount: def.projectile.preExplosionSpawnThingCount, applyDamageToExplosionCellsNeighbors: def.projectile.applyDamageToExplosionCellsNeighbors, chanceToStartFire: def.projectile.explosionChanceToStartFire, damageFalloff: def.projectile.explosionDamageFalloff, ignoredThings: null, affectedAngle: null, doVisualEffects: true, propagationSpeed: def.projectile.damageDef.expolosionPropagationSpeed, excludeRadius: 0f, doSoundEffects: true, screenShakeFactor: def.projectile.screenShakeFactor);
    }
    private void ThrowDebugText(string text)
    {
        if (DebugViewSettings.drawShooting)
        {
            MoteMaker.ThrowText(caster.DrawPos, caster.Map, text);
        }
    }
    private void ThrowDebugText(string text, IntVec3 c)
    {
        if (DebugViewSettings.drawShooting)
        {
            MoteMaker.ThrowText(c.ToVector3Shifted(), caster.Map, text);
        }
    }
}

